Analyse de sentiments :
Temoignages des employés sur le site de Glassdoor

Présenté par : Mohammad MOEZZIBADI

Novembre 2021

Introduction

Problématique

  • Avis ironiques :
Exemple d’avis
  • Un avis mélangé : Le poste [à l’entreprise] était horrible et la direction n’est pas capable de reconnaître les réalisations, mais une bonne opportunité de travailler avec mes collègues m’a incité à y aller tous les jours.

Plan général du code

Plan général de scraping

  • 16768 avis sur les entreprises situées en France qui recrutent des data scientists
 Scraping ciblé des pages : I) configuration de la recherche II) changement des pages avec *selenium* III) un exemple de témoignages d'un employé Scraping ciblé des pages : I) configuration de la recherche II) changement des pages avec *selenium* III) un exemple de témoignages d'un employé

Scraping ciblé des pages : I) configuration de la recherche II) changement des pages avec selenium III) un exemple de témoignages d’un employé

Construction de base de donées

  • Construire un dataframe a partir du fichier json de résultats scrapés
Automatisation dans le menu bar

df = df.drop(['level_0', 'level_1'], axis=1)
df = df[0].apply(pd.Series)
...
df['Date'] = [','.join(map(str, l)) for l in df[2]]
df['Date'] = df['Date'].str.split('-', n = 1, expand = True)[0
to_replace = [' ','sept.','août', 'juil.', 'mai', "avr.", ..."]
replace_with = ['','sep','aug','jul', 'may' ,"apr", ...]
df['Date'] = df['Date'].replace(to_replace, replace_with, regex=True)
df = df.dropna(axis=0, how="any", thresh=None, subset=None, inplace=False)
df['Date'] = pd.to_datetime(df['Date'],format='%d%b%Y')

Nuages de mots

Nuage des mots des avis **avant 2016** : positives (vert) et négatives (rouge)Nuage des mots des avis **avant 2016** : positives (vert) et négatives (rouge)

Nuage des mots des avis avant 2016 : positives (vert) et négatives (rouge)

Nuage des mots des avis **après 2016** : positives (vert) et négatives (rouge)Nuage des mots des avis **après 2016** : positives (vert) et négatives (rouge)

Nuage des mots des avis après 2016 : positives (vert) et négatives (rouge)

Classification de Naive Bayes

\(\color{red}{\displaystyle p(D\mid C)=\prod _{i}p(w_{i}\mid C)\,} \color{red}{=>} \color{red}{\displaystyle p(C\mid D)\,} \color{red}= \color{red}?\)
\(\begin{cases} {\displaystyle p(D\mid P)=\prod _{i}p(w_{i}\mid P)\,} \\ {\displaystyle p(D\mid \neg P)=\prod _{i}p(w_{i}\mid \neg P)\,}\end{cases}\) => Bayes’ theorem : \({\displaystyle p(C\mid D)={\frac {p(C)\,p(D\mid C)}{p(D)}}}\)
\[ \begin{cases} {\displaystyle p(P\mid D)={p(P) \over p(D)}\,\prod _{i}p(w_{i}\mid P)} \\ {\displaystyle p(\neg P\mid D)={p(\neg P) \over p(D)}\,\prod _{i}p(w_{i}\mid \neg P)} \end{cases} => {\displaystyle {p(P\mid D) \over p(\neg P\mid D)}={p(P) \over p(\neg P)}\,\prod _{i}{p(w_{i}\mid P) \over p(w_{i}\mid \neg P)}} \]

\({\displaystyle \ln {p(P\mid D) \over p(\neg P\mid D)}=\ln {p(P) \over p(\neg P)}+\sum _{i}\ln {p(w_{i}\mid P) \over p(w_{i}\mid \neg P)}}\)

\({\displaystyle p(P\mid D)>p(\neg P\mid D)}\) => \({\displaystyle \ln {p(P\mid D) \over p(\neg P\mid D)}>0}\)

Classification de Naive Bayes

\({\displaystyle p(D\mid C)=\prod _{i}p(w_{i}\mid C)\,}\) => \({\displaystyle p(C\mid D)\,} = ?\)
\(\color{red}{\begin{cases} \color{red}{\displaystyle p(D\mid P)=\prod _{i}p(w_{i}\mid P)\,} \\ \color{red}{\displaystyle p(D\mid \neg P)=\prod _{i}p(w_{i}\mid \neg P)\,}\end{cases}}\) \(\color{red}{=> Bayes' \ theorem :}\) \(\color{red}{\displaystyle p(C\mid D)={\frac {p(C)\,p(D\mid C)}{p(D)}}}\)
\[ \begin{cases} {\displaystyle p(P\mid D)={p(P) \over p(D)}\,\prod _{i}p(w_{i}\mid P)} \\ {\displaystyle p(\neg P\mid D)={p(\neg P) \over p(D)}\,\prod _{i}p(w_{i}\mid \neg P)} \end{cases} => {\displaystyle {p(P\mid D) \over p(\neg P\mid D)}={p(P) \over p(\neg P)}\,\prod _{i}{p(w_{i}\mid P) \over p(w_{i}\mid \neg P)}} \]

\({\displaystyle \ln {p(P\mid D) \over p(\neg P\mid D)}=\ln {p(P) \over p(\neg P)}+\sum _{i}\ln {p(w_{i}\mid P) \over p(w_{i}\mid \neg P)}}\)

\({\displaystyle p(P\mid D)>p(\neg P\mid D)}\) => \({\displaystyle \ln {p(P\mid D) \over p(\neg P\mid D)}>0}\)

Classification de Naive Bayes

\({\displaystyle p(D\mid C)=\prod _{i}p(w_{i}\mid C)\,}\) => \({\displaystyle p(C\mid D)\,} = ?\)
\(\begin{cases} {\displaystyle p(D\mid P)=\prod _{i}p(w_{i}\mid P)\,} \\ {\displaystyle p(D\mid \neg P)=\prod _{i}p(w_{i}\mid \neg P)\,}\end{cases}\) => Bayes’ theorem : \({\displaystyle p(C\mid D)={\frac {p(C)\,p(D\mid C)}{p(D)}}}\)
\[ \color{red}{\begin{cases} {\displaystyle p(P\mid D)={p(P) \over p(D)}\,\prod _{i}p(w_{i}\mid P)} \\ {\displaystyle p(\neg P\mid D)={p(\neg P) \over p(D)}\,\prod _{i}p(w_{i}\mid \neg P)} \end{cases}} \color{red}{=>} \color{red}{\displaystyle {p(P\mid D) \over p(\neg P\mid D)}={p(P) \over p(\neg P)}\,\prod _{i}{p(w_{i}\mid P) \over p(w_{i}\mid \neg P)}} \]

\({\displaystyle \ln {p(P\mid D) \over p(\neg P\mid D)}=\ln {p(P) \over p(\neg P)}+\sum _{i}\ln {p(w_{i}\mid P) \over p(w_{i}\mid \neg P)}}\)

\({\displaystyle p(P\mid D)>p(\neg P\mid D)}\) => \({\displaystyle \ln {p(P\mid D) \over p(\neg P\mid D)}>0}\)

Classification de Naive Bayes

\({\displaystyle p(D\mid C)=\prod _{i}p(w_{i}\mid C)\,}\) => \({\displaystyle p(C\mid D)\,} = ?\)
\(\begin{cases} {\displaystyle p(D\mid P)=\prod _{i}p(w_{i}\mid P)\,} \\ {\displaystyle p(D\mid \neg P)=\prod _{i}p(w_{i}\mid \neg P)\,}\end{cases}\) => Bayes’ theorem : \({\displaystyle p(C\mid D)={\frac {p(C)\,p(D\mid C)}{p(D)}}}\)
\[ \begin{cases} {\displaystyle p(P\mid D)={p(P) \over p(D)}\,\prod _{i}p(w_{i}\mid P)} \\ {\displaystyle p(\neg P\mid D)={p(\neg P) \over p(D)}\,\prod _{i}p(w_{i}\mid \neg P)} \end{cases} => {\displaystyle {p(P\mid D) \over p(\neg P\mid D)}={p(P) \over p(\neg P)}\,\prod _{i}{p(w_{i}\mid P) \over p(w_{i}\mid \neg P)}} \]

\(\color{red}{\displaystyle \ln {p(P\mid D) \over p(\neg P\mid D)}=\ln {p(P) \over p(\neg P)}+\sum _{i}\ln {p(w_{i}\mid P) \over p(w_{i}\mid \neg P)}}\)

\({\displaystyle p(P\mid D)>p(\neg P\mid D)}\) => \({\displaystyle \ln {p(P\mid D) \over p(\neg P\mid D)}>0}\)

Classification de Naive Bayes

\({\displaystyle p(D\mid C)=\prod _{i}p(w_{i}\mid C)\,}\) => \({\displaystyle p(C\mid D)\,} = ?\)
\(\begin{cases} {\displaystyle p(D\mid P)=\prod _{i}p(w_{i}\mid P)\,} \\ {\displaystyle p(D\mid \neg P)=\prod _{i}p(w_{i}\mid \neg P)\,}\end{cases}\) => Bayes’ theorem : \({\displaystyle p(C\mid D)={\frac {p(C)\,p(D\mid C)}{p(D)}}}\)
\[ \begin{cases} {\displaystyle p(P\mid D)={p(P) \over p(D)}\,\prod _{i}p(w_{i}\mid P)} \\ {\displaystyle p(\neg P\mid D)={p(\neg P) \over p(D)}\,\prod _{i}p(w_{i}\mid \neg P)} \end{cases} => {\displaystyle {p(P\mid D) \over p(\neg P\mid D)}={p(P) \over p(\neg P)}\,\prod _{i}{p(w_{i}\mid P) \over p(w_{i}\mid \neg P)}} \]

\({\displaystyle \ln {p(P\mid D) \over p(\neg P\mid D)}=\ln {p(P) \over p(\neg P)}+\sum _{i}\ln {p(w_{i}\mid P) \over p(w_{i}\mid \neg P)}}\)

\(\color{red}{\displaystyle p(P\mid D)>p(\neg P\mid D)}\) \(\color{red}{=>}\) \(\color{red}{\displaystyle \ln {p(P\mid D) \over p(\neg P\mid D)}>0}\)

Classification de Naive Bayes

Module :

from sklearn.naive_bayes import MultinomialNB
Matrice de confusion

Distribution de Dirichlet

  1. Non-Negative Matrix Factorization (NMF)
  2. Latent Semantic Analysis or Latent Semantic Indexing (LSA or LSI)
  3. Latent Dirichlet Allocation

Latent Dirichlet Allocation :

\[ P(W,Z,\theta ,\varphi; \color{red}\alpha,\color{red}\beta) = \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\ \Pi_{j=1}^{M}P(\theta_j;\color{red}\alpha)\ \Pi_{j=1}^{K}P(\varphi_i;\color{red}{\beta}) \ \Pi_{t=1}^{N}P(Z_{j,t}|\theta_j)P(W_{j,t}|\varphi_{Z_{j,t}})\]

  • \(\alpha\) & \(\beta\) — la distribution Dirichlet
  • \(\theta\) & \(\varphi\) — la distribution multinomiale
  • \(Z\) — un ensemble de sujets
  • \(W\) — un ensemble de mots

Distribution de Dirichlet

  • \(0< \alpha << 1\):

    \((\color{red}{1.0} , 0.0, 0.0)\) ou

    \((0.0, \color{red}{1.0}, 0.0)\) ou

    \((0.0, 0.0, \color{red}{1.0})\)

  • \(\alpha ≈ 1\):

    Distribution uniforme

  • \(\alpha > 1\) :

    Une mixité égale des sujets:

    \((0.4, 0.3, 0.3)\)

Latent Dirichlet Allocation

  1. For \(j = 1\) : \(M\) (le nombre de documents)
    • Paramétrage de la distribution des sujets pour chaque document
    • \(\theta_j\) ~ Dirichlet (\(\alpha\))
  2. For \(i = 1\) : \(K\) (le nombre de sujets)
    • Paramétrage de la distribution des mots pour chaque sujet
    • \(\varphi_i\) ~ Dirichlet (\(\beta\))
  1. For \(t = 1\) : \(N\) (le nombre de mots dans le document \(j\))
    • Choisir le Topic pour le mot \(t\)
    • \(z_{j,t}\) ~ Multinomial (\(\theta_j\))
    • choisir le mot à partir de la distribution de mots pour chaque sujet \(z\)
    • \(\omega_{j,t}\) ~ Multinomial (\(\varphi^{(z_{j,t})}\))

Latent Dirichlet Allocation

ghtr

Latent Dirichlet Allocation

Steps!

1 : Chargement des données

2 : Nettoyage des données

3 : Modélisation d’expressions : bi-grammes et tri-grammes

4 : Transformation de données : Corpus et Dictionnaire

5 : Modèle de base

6 : Optimisation des hyperparamètres

7 : Modèle final

8 : Visualisation des résultats

Modules!

import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel
# spacy pour lemmatization
import spacy
# Plotting tools
import pyLDAvis
import pyLDAvis.gensim_models as gensimvis
import matplotlib.pyplot as plt

Hyperparmeter Tuning

  • Module : gensim.models.LdaMulticore
    Demande d’affichage des notifications par FB
  • Nombre de sujet \(K\)
  • Hyperparamètre Dirichlet \(\alpha\) : Densité de Document-Topic
  • Hyperparamètre Dirichlet \(\beta\): Densité de mot-Topic

Visualisation de LDA (pyLDAvis)

Conclusion

  • Efficacité de Selénium : Glassdoor a une API disponible, mais pas pour le contenu qu’on recherche

  • On a construit un modèle LDA à l’aide de Gensim et optimisé les hyperparamètres LDA.

  • Comparaison de l’utilité des deux méthodes NLP : LDA (non-supervisé) et Naive Bayes (supervisé)

  • Inéfficacité de LDA pour les textes courts (tweets ou des commentaires) - un meilleur choix : *Biterm Topic Model